#ifndef ALIYUN_IOT_PLATFORM_NETWORK_H
#define ALIYUN_IOT_PLATFORM_NETWORK_H

#include "lwip/sockets.h"
#include "lwip/netdb.h"
#include "lwip/tcp.h"
#include "lwip/err.h"
#include "aliyun_iot_common_datatype.h"
#include "aliyun_iot_platform_timer.h"


#define INADDR_ANY_IOT      0

#define AF_UNSPEC_IOT       0
#define AF_INET_IOT         2
#define PF_INET_IOT         AF_INET_IOT
#define PF_UNSPEC_IOT       AF_UNSPEC_IOT

#define AI_PASSIVE_IOT          1

#define SOCK_STREAM_IOT     1
#define SOCK_DGRAM_IOT      2
#define SOCK_RAW_IOT        3

#define IPPROTO_IP_IOT      0
#define IPPROTO_TCP_IOT     6
#define IPPROTO_UDP_IOT     17
#define SOL_SOCKET_IOT      0x1012

#define MSG_PEEK_IOT       0x01
#define MSG_WAITALL_IOT    0x02
#define MSG_OOB_IOT        0x04
#define MSG_DONTWAIT_IOT   0x08
#define MSG_MORE_IOT       0x10


#define  SO_DEBUG_IOT       0x0001   /* Unimplemented: turn on debugging info recording */
#define  SO_ACCEPTCONN_IOT  0x0002   /* socket has had listen() */
#define  SO_REUSEADDR_IOT   0x0004   /* Allow local address reuse */
#define  SO_KEEPALIVE_IOT   0x0008   /* keep connections alive */
#define  SO_DONTROUTE_IOT   0x0010   /* Unimplemented: just use interface addresses */
#define  SO_BROADCAST_IOT   0x0020   /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
#define  SO_LINGER_IOT      0x0080   /* linger on close if data present */
#define  SO_OOBINLINE_IOT   0x0100   /* Unimplemented: leave received OOB data in line */
#define  SO_SNDBUF_IOT      0x1001    /* Unimplemented: send buffer size */
#define  SO_RCVBUF_IOT      0x1002    /* receive buffer size */
#define  SO_SNDLOWAT_IOT    0x1003    /* Unimplemented: send low-water mark */
#define  SO_RCVLOWAT_IOT    0x1004    /* Unimplemented: receive low-water mark */
#define  SO_SNDTIMEO_IOT    0x1005    /* Unimplemented: send timeout */
#define  SO_RCVTIMEO_IOT    0x1006    /* receive timeout */
#define  SO_ERROR_IOT       0x1007    /* get error status and clear */
#define  SO_TYPE_IOT        0x1008    /* get socket type */
#define  SO_NO_CHECK_IOT    0x100a    /* don't create UDP checksum */

#define  TCP_NODELAY_IOT    0x1010
#define  TCP_CORK_IOT       0x1011

#define O_NONBLOCK_IOT  1
#define F_GETFL_IOT     0x2
#define F_SETFL_IOT     0x3


#define EINTR_IOT              -2
#define EBADF_IOT              -3
#define EAGAIN_IOT   -4
#define EFAULT_IOT   -5
#define EBUSY_IOT    -6
#define EINVAL_IOT   -7
#define ENFILE_IOT   -8
#define EMFILE_IOT   -9
#define ENOSPC_IOT   -10
#define EPIPE_IOT    -11
#define EWOULDBLOCK_IOT   -12
#define ENOTSOCK_IOT      -13
#define ENOPROTOOPT_IOT   -14
#define EADDRINUSE_IOT    -15
#define EADDRNOTAVAIL_IOT  -16
#define ENETDOWN_IOT      -17
#define ENETUNREACH_IOT   -18
#define ENETRESET_IOT     -19
#define ECONNRESET_IOT    -20
#define ENOBUFS_IOT       -21
#define EISCONN_IOT       -22
#define ENOTCONN_IOT      -23
#define ETIMEDOUT_IOT     -24
#define ECONNREFUSED_IOT  -25
#define EHOSTDOWN_IOT     -26
#define EHOSTUNREACH_IOT  -27
#define ENOMEM_IOT        -28
#define EMSGSIZE_IOT      -29

typedef enum ALIYUN_NETWORK_ERROR
{
    NETWORK_PARAM_ERROR = -31,
    NETWORK_MSG_TOO_LONG = -30,
    NETWORK_OUT_OF_MEMORY = -29,
    NETWORK_SIGNAL_INTERRUPT = -28,
    NETWORK_BAD_FILEFD = -27,
    NETWORK_TRYAGAIN = -26,
    NETWORK_BADADDRESS = -25,
    NETWORK_RESOURCE_BUSY = -24,
    NETWORK_INVALID_ARGUMENT = -23,
    NETWORK_FILE_TABLE_OVERFLOW = -22,
    NETWORK_TOO_MANY_OPEN_FILES = -21,
    NETWORK_NO_SPACE_LEFT_ON_DEVICE = -20,
    NETWORK_BROKEN_PIPE = -19,
    NETWORK_OPERATION_BLOCK = -18,
    NETWORK_OPERATION_ON_NONSOCKET = -17,
    NETWORK_PROTOCOL_NOT_AVAILABLE = -16,
    NETWORK_ADDRESS_ALREADY_IN_USE = -15,
    NETWORK_CANNOT_ASSIGN_REQUESTED_ADDRESS = -14,
    NETWORK_NETWORK_IS_DOWN = -13,
    NETWORK_NETWORK_IS_UNREACHABLE = -12,
    NETWORK_CONNECT_RESET = -11,
    NETWORK_CONNECT_RESET_BY_PEER = -10,
    NETWORK_NO_BUFFER_SPACE = -9,
    NETWORK_ALREADY_CONNECTED = -8,
    NETWORK_IS_NOT_CONNECTED = -7,
    NETWORK_CONNECTION_TIMED_OUT = -6,
    NETWORK_CONNECTION_REFUSED = -5,
    NETWORK_HOST_IS_DOWN = -4,
    NETWORK_NO_ROUTE_TO_HOST = -3,
    NETWORK_TIMEOUT = -2,
    NETWORK_FAIL = -1,
    NETWORK_SUCCESS = 0,

}ALIYUN_NETWORK_ERROR_E;

typedef struct ALIYUN_NETWORK_IN_ADDR
{
    UINT32 s_addr;
}ALIYUN_NETWORK_IN_ADDR_S;

typedef struct ALIYUN_NETWORK_SOCKADDR
{
    UINT8 sa_family;
    INT8  sa_data[14];
}ALIYUN_NETWORK_SOCKADDR_S;

typedef struct ALIYUN_NETWORK_SOCKADDR_IN
{
    UINT8  sin_family;
    UINT16 sin_port;
    ALIYUN_NETWORK_IN_ADDR_S sin_addr;
    INT8   sin_zero[8];
}ALIYUN_NETWORK_SOCKADDR_IN_S;

typedef struct ALIYUN_NETWORK_FD_SET
{
    fd_set sets;
}ALIYUN_NETWORK_FD_SET_S;

typedef struct ALIYUN_NETWORK_ADDRINFO
{
    INT32                             ai_flags;      /* Input flags. */
    INT32                             ai_family;     /* Address family of socket. */
    INT32                             ai_socktype;   /* Socket type. */
    INT32                             ai_protocol;   /* Protocol of socket. */
    INT32                             ai_addrlen;    /* Length of socket address. */
    ALIYUN_NETWORK_SOCKADDR_IN_S      *ai_addr;       /* Socket address of socket. */
    INT8                              *ai_canonname;  /* Canonical name of service location. */
    struct ALIYUN_NETWORK_ADDRINFO    *ai_next;       /* Pointer to next in list. */
}ALIYUN_NETWORK_ADDRINFO_S;

INT32 aliyun_iot_network_socket(INT32 af,INT32 type,INT32 protocol);

INT32 aliyun_iot_network_bind(INT32 sockFd, ALIYUN_NETWORK_SOCKADDR_IN_S *sockAddr, INT32 addrLen );

INT32 aliyun_iot_network_listen( INT32 sockFd, INT32 backlog);

INT32 aliyun_iot_network_connect(INT32 sockfd,ALIYUN_NETWORK_SOCKADDR_IN_S * serv_addr,INT32 addrlen);

INT32 aliyun_iot_network_send(INT32 sockFd, VOID *buf, INT32 nbytes, UINT32 flags);

INT32 aliyun_iot_network_recv(INT32 sockFd, VOID *buf, INT32 nbytes, UINT32 flags);

INT32 aliyun_iot_network_read(INT32 sockFd, VOID *buf, INT32 nbytes);

INT32 aliyun_iot_network_write(INT32 sockFd, const VOID *buf, INT32 nbytes);

INT32 aliyun_iot_network_select(INT32 maxFd,ALIYUN_NETWORK_FD_SET_S *readset,ALIYUN_NETWORK_FD_SET_S*writeset,ALIYUN_NETWORK_FD_SET_S*exceptset,ALIYUN_IOT_TIME_TYPE_S * timeout);

VOID aliyun_iot_network_FD_SET(INT32 fd,ALIYUN_NETWORK_FD_SET_S *set);

VOID aliyun_iot_network_FD_CLR(INT32 fd,ALIYUN_NETWORK_FD_SET_S *set);

INT32 aliyun_iot_network_FD_ISSET(INT32 fd,ALIYUN_NETWORK_FD_SET_S *set);

VOID aliyun_iot_network_FD_ZERO(ALIYUN_NETWORK_FD_SET_S* set);

INT32 aliyun_iot_network_setsockopt(INT32 fd,INT32 level,INT32 optname,VOID*optval,INT32 optlen);

INT32 aliyun_iot_network_get_nonblock(INT32 fd);

INT32 aliyun_iot_network_set_nonblock(INT32 fd);

INT32 aliyun_iot_network_set_block(INT32 fd);

INT32 aliyun_iot_network_close(INT32 fd);

INT32 aliyun_iot_network_shutdown(INT32 fd,INT32 how);

INT32 aliyun_iot_network_getaddrinfo(const INT8*host,const INT8*service,ALIYUN_NETWORK_ADDRINFO_S*hints,ALIYUN_NETWORK_ADDRINFO_S**result);

VOID aliyun_iot_network_freeaddrinfo(ALIYUN_NETWORK_ADDRINFO_S*result);

INT32 aliyun_iot_get_errno(VOID);

#endif


